CXX = g++
CXXFLAGS = -Wall -Wextra -O2 -g -std=c++11
LDFLAGS = -pthread

# 目录定义
OBJ_DIR = obj

# 目标文件
SERVER_TARGET = redis_server
CLIENT_TARGET = client
INTERACTIVE_TARGET = interactive_client
AUTO_TEST_TARGET = auto_test

# 源文件
SERVER_SOURCES = redis_server.cpp hashtable.cpp avl.cpp heap.cpp zset.cpp thread_pool.cpp
CLIENT_SOURCES = client.cpp
INTERACTIVE_SOURCES = interactive_client.cpp
AUTO_TEST_SOURCES = auto_test.cpp

# 对象文件（放在obj目录中）
SERVER_OBJECTS = $(addprefix $(OBJ_DIR)/, $(SERVER_SOURCES:.cpp=.o))
CLIENT_OBJECTS = $(addprefix $(OBJ_DIR)/, $(CLIENT_SOURCES:.cpp=.o))
INTERACTIVE_OBJECTS = $(addprefix $(OBJ_DIR)/, $(INTERACTIVE_SOURCES:.cpp=.o))
AUTO_TEST_OBJECTS = $(addprefix $(OBJ_DIR)/, $(AUTO_TEST_SOURCES:.cpp=.o))

# 头文件
HEADERS = common.h hashtable.h avl.h heap.h zset.h thread_pool.h list.h

# 默认目标
all: $(SERVER_TARGET) $(CLIENT_TARGET) $(INTERACTIVE_TARGET) $(AUTO_TEST_TARGET)

# 创建obj目录
$(OBJ_DIR):
	mkdir -p $(OBJ_DIR)

# 链接服务器目标
$(SERVER_TARGET): $(SERVER_OBJECTS)
	$(CXX) $(SERVER_OBJECTS) -o $(SERVER_TARGET) $(LDFLAGS)

# 链接客户端目标
$(CLIENT_TARGET): $(CLIENT_OBJECTS)
	$(CXX) $(CLIENT_OBJECTS) -o $(CLIENT_TARGET) $(LDFLAGS)

# 链接交互式客户端目标
$(INTERACTIVE_TARGET): $(INTERACTIVE_OBJECTS)
	$(CXX) $(INTERACTIVE_OBJECTS) -o $(INTERACTIVE_TARGET) $(LDFLAGS)

# 链接自动化测试程序
$(AUTO_TEST_TARGET): $(AUTO_TEST_OBJECTS)
	$(CXX) $(AUTO_TEST_OBJECTS) -o $(AUTO_TEST_TARGET) $(LDFLAGS)

# 编译规则（生成到obj目录）
$(OBJ_DIR)/%.o: %.cpp $(HEADERS) | $(OBJ_DIR)
	$(CXX) $(CXXFLAGS) -c $< -o $@

# 清理
clean:
	rm -rf $(OBJ_DIR) $(SERVER_TARGET) $(CLIENT_TARGET) $(INTERACTIVE_TARGET) $(AUTO_TEST_TARGET)

# 重新编译
rebuild: clean all

# 运行服务器
run-server: $(SERVER_TARGET)
	./$(SERVER_TARGET)

# 运行客户端
run-client: $(CLIENT_TARGET)
	./$(CLIENT_TARGET)

# 运行交互式客户端
run-interactive: $(INTERACTIVE_TARGET)
	./$(INTERACTIVE_TARGET)

# 运行自动化测试
auto-test: $(AUTO_TEST_TARGET)
	@echo "启动Redis服务器..."
	@./$(SERVER_TARGET) & echo $$! > server.pid
	@sleep 1
	@echo "运行自动化测试..."
	@./$(AUTO_TEST_TARGET) || true
	@echo "停止Redis服务器..."
	@kill `cat server.pid` 2>/dev/null || true
	@rm -f server.pid

# 测试（先启动服务器，然后运行客户端）
test: $(SERVER_TARGET) $(CLIENT_TARGET)
	@echo "请在另一个终端运行: make run-server"
	@echo "然后运行: make run-client"

# 交互式测试
interactive-test: $(SERVER_TARGET) $(INTERACTIVE_TARGET)
	@echo "请在另一个终端运行: make run-server"
	@echo "然后运行: make run-interactive"

# 调试运行
debug: $(SERVER_TARGET)
	gdb ./$(SERVER_TARGET)

# 显示编译信息
info:
	@echo "项目信息:"
	@echo "服务器源文件: $(SERVER_SOURCES)"
	@echo "客户端源文件: $(CLIENT_SOURCES)"
	@echo "交互客户端源文件: $(INTERACTIVE_SOURCES)"
	@echo "自动化测试源文件: $(AUTO_TEST_SOURCES)"
	@echo "服务器对象文件: $(SERVER_OBJECTS)"
	@echo "客户端对象文件: $(CLIENT_OBJECTS)"
	@echo "交互客户端对象文件: $(INTERACTIVE_OBJECTS)"
	@echo "自动化测试对象文件: $(AUTO_TEST_OBJECTS)"
	@echo "对象文件目录: $(OBJ_DIR)"

.PHONY: all clean rebuild run-server run-client run-interactive test interactive-test debug info 